package com.wtb.javatool.common;

import lombok.Data;

import java.util.HashMap;
import java.util.Map;

@Data
public class Result<T> {
    // 状态码（通过状态码推断是否成功，例如 2xx 为成功）
    private Integer code;
    // 提示消息
    private String message;
    // 核心业务数据（泛型类型安全）
    private T data;
    // 动态附加元数据（无需泛型）
    private Map<String, Object> map;

    // 私有构造方法，强制使用静态工厂方法
    private Result() {
    }

    // ---------------------------
    // 静态工厂方法（快速创建成功/失败对象）
    // ---------------------------

    /**
     * 成功响应（携带核心数据）
     */
    public static <T> Result<T> success(T data) {
        Result<T> result = new Result<>();
        result.code = ResultCode.SUCCESS.getCode();
        result.message = ResultCode.SUCCESS.getMsg();
        result.data = data;
        return result;
    }

    /**
     * 成功响应（无核心数据）
     */
    public static Result<Void> success() {
        return success(null);
    }

    /**
     * 错误响应（自定义错误码和消息）
     */
    public static <T> Result<T> error(int code, String message) {
        Result<T> result = new Result<>();
        result.code = code;
        result.message = message;
        return result;
    }

    /**
     * 错误响应（自定义消息）
     */
    public static <T> Result<T> error( String message) {
        Result<T> result = new Result<>();
        result.code = ResultCode.ERROR.getCode();
        result.message = message;
        return result;
    }

    /**
     * 错误响应（默认错误码和消息）
     */
    public static <T> Result<T> error() {
        return error(ResultCode.ERROR.getCode(), ResultCode.ERROR.getMsg());
    }

    // ---------------------------
    // 链式方法（动态补充字段）
    // ---------------------------

    /**
     * 链式设置消息
     */
    public Result<T> message(String message) {
        this.message = message;
        return this;
    }

    /**
     * 链式设置状态码
     */
    public Result<T> code(Integer code) {
        this.code = code;
        return this;
    }

    /**
     * 链式添加元数据
     */
    public Result<T> put(String key, Object value) {
        if (this.map == null) {
            this.map = new HashMap<>();
        }
        this.map.put(key, value);
        return this;
    }

}